﻿Public Class frmPrincipal

    Private Sub btnGenerar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerar.Click
        Dim msg As String = ""
        If Not IsNumeric(txtCant.Text) Then msg = vbCrLf & " - Usuarios"
        If txtApp.Text = "" Then msg = msg & vbCrLf & " - Aplicación"
        If Not IsNumeric(txtVer.Text) Then msg = msg & vbCrLf & " - Versión"
        If msg <> "" Then
            MsgBox("Ingrese los siguientes campos:" & msg, MsgBoxStyle.Exclamation, "Generador de Claves")
        Else
            txtCla.Text = GeneraClave(CInt(txtCant.Text))
        End If

    End Sub

    Private Function Num2Bin(ByVal num As Long) As String
        On Error Resume Next
        Dim i As Integer, d As Single
        Num2Bin = ""
        d = num
        For i = 0 To 7 ' 31
            If d / 2 <> Int(d / 2) Then
                Num2Bin = "1" & Num2Bin
            Else
                Num2Bin = "0" & Num2Bin
            End If
            d = Int(d / 2)
        Next
    End Function

    Private Function Bin2Num(ByVal Bin As String) As Long
        On Error Resume Next
        Dim i As Integer
        For i = 1 To Len(Bin)
            Bin2Num = Bin2Num * 2
            If Mid(Bin, i, 1) = "1" Then
                Bin2Num = Bin2Num + 1
            End If
        Next
    End Function

    Private Function ExtraeValApp(ByVal strNomApp As String) As String
        On Error Resume Next
        Dim strApp As String, i As Integer
        Dim Num1 As Integer, Num2 As Integer
        Dim cant1 As Integer, cant2 As Integer
        strApp = UCase(Replace(Trim(strNomApp), " ", ""))
        For i = 1 To Len(strApp)
            If (i Mod 2) > 0 Then
                Num1 = Num1 + Asc(Mid(strApp, i, 1))
                cant1 = cant1 + 1
            Else
                Num2 = Num2 + Asc(Mid(strApp, i, 1))
                cant2 = cant2 + 1
            End If
        Next i
        Num1 = Math.Round(Num1 / cant1)
        Num2 = Math.Round(Num2 / cant2)
        ExtraeValApp = CStr(Num1) & CStr(Num2)
    End Function

    Public Function SumaDigitos(ByVal num As Integer) As Integer
        On Error Resume Next
        Dim strDig As String, i As Integer
        strDig = CStr(num)
        For i = 1 To Len(strDig)
            SumaDigitos = SumaDigitos + Mid(strDig, i, 1)
        Next i

        strDig = CStr(SumaDigitos)
        SumaDigitos = 0
        For i = 1 To Len(strDig)
            SumaDigitos = SumaDigitos + Mid(strDig, i, 1)
        Next i
    End Function

    Private Function GeneraClave(ByVal cant As Integer) As String
        Dim strCant As String
        Dim Num1 As Integer, Num2 As Integer
        Dim Num5 As Integer, Num6 As Integer
        GeneraClave = ""
        strCant = Num2Bin(cant)
        Dim bCad(8) As String
        bCad(7) = IIf(Mid(strCant, 6, 1) = "1", "0", "1")
        bCad(6) = IIf(Mid(strCant, 3, 1) = "1", "0", "1")
        bCad(5) = IIf(Mid(strCant, 8, 1) = "1", "0", "1")
        bCad(4) = IIf(Mid(strCant, 5, 1) = "1", "0", "1")
        bCad(3) = IIf(Mid(strCant, 1, 1) = "1", "0", "1")
        bCad(2) = IIf(Mid(strCant, 7, 1) = "1", "0", "1")
        bCad(1) = IIf(Mid(strCant, 4, 1) = "1", "0", "1")
        bCad(0) = IIf(Mid(strCant, 2, 1) = "1", "0", "1")

        Num1 = Bin2Num("0000" & bCad(7) & bCad(6) & bCad(5) & bCad(4))
        Num2 = Bin2Num("0000" & bCad(3) & bCad(2) & bCad(1) & bCad(0))

        strCant = ExtraeValApp(txtApp.Text)
        Num5 = CInt(Strings.Left(strCant, 2))
        Num6 = CInt(Strings.Right(strCant, 2))

        Dim bKey(12) As String
        bKey(11) = "?"
        bKey(10) = "?"
        bKey(9) = Chr(81 - Num1 - txtVer.Text)
        bKey(8) = Chr(Num5)
        bKey(7) = Chr(90 - Num2)
        bKey(6) = Chr(Num6 - txtVer.Text * 2)
        bKey(5) = "?"
        bKey(4) = Chr(Num6)
        bKey(3) = "?"
        bKey(2) = Chr(65 + Num1)
        bKey(1) = Chr(72 + Num2)
        bKey(0) = "?"

        bKey(3) = Chr(Math.Round((Asc(bKey(9)) + Asc(bKey(8)) + Asc(bKey(7)) + Asc(bKey(6)) + Asc(bKey(4)) + Asc(bKey(2)) + Asc(bKey(1))) / 7))
        bKey(5) = CStr(Asc(bKey(3)) Mod 10)
        bKey(0) = Chr(93 - (txtVer.Text * 3) - CInt(bKey(5)))
        bKey(10) = CStr(SumaDigitos(Asc(bKey(0)) + Asc(bKey(1))))
        bKey(11) = CStr(SumaDigitos(Asc(bKey(4)) + Asc(bKey(9)) - Asc(bKey(7))))

        Dim i As Integer
        For i = 11 To 0 Step -1
            GeneraClave = GeneraClave & bKey(i)
        Next i
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalir.Click
        Me.Close()
    End Sub

    Private Sub btnAcerca_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAcerca.Click
        MsgBox("Desarrollado por:" & vbCrLf & "Rafael Michuy Gutierrez" & vbCrLf & "Copyright (c) 2011", MsgBoxStyle.Information, "Generador de Claves")
    End Sub

End Class
